﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using UTSDAL.LINQSQL.DAO;
using UTSDAL.LINQSQL.Model;
using log4net;
using UTSDAL.LINQSQL.Views;
using DayPilot.Web.Ui;
using UTSDAL.MAIL;
using System.Threading;
using UTSDAL.LINQSQL.Helper;
using UTSDAL.SQL;
using System.Data.SqlClient;

public partial class pages_admin_generation : System.Web.UI.Page
{

    private static readonly ILog log = LogManager.GetLogger(typeof(pages_admin_generation));

    protected void Page_Load(object sender, EventArgs e)
    {
        ObjectUtils.initCalendar(EventCalendar);
        
        EventCalendar.DataStartField = "StartTime";
        EventCalendar.DataEndField = "EndTime";
        
        EventCalendar.DataTextField = "CalendarDisplayString";
        EventCalendar.DataValueField = "TimetableEventId";
        
        List<TimetableEventView> views = timetableEventDAO.getTimetableEventsViewForSemester(semesterDAO.getCurrentSemester());

        log.Debug("Views = "+views.Count);
        log.Debug("Calendar Start = " + EventCalendar.StartDate);
        foreach(TimetableEventView view in views)
        {
            log.Debug("Start = " + view.StartTime);
        }


        List<TimetableEvent> events = timetableEventDAO.getTimetableEventsForSemester(semesterDAO.getCurrentSemester());

        foreach (TimetableEvent ev in events)
        {
            log.Debug("Event = " + ev.StartTime);
        }

        EventCalendar.DataSource = views;
        EventCalendar.DataBind();
    }

    private SemesterDAO semesterDAO = new SemesterDAO();

    private ModuleEventDAO moduleEventDAO = new ModuleEventDAO();

    private TimetableEventDAO timetableEventDAO = new TimetableEventDAO();

    private CohortModuleDAO cohortModuleDAO = new CohortModuleDAO();


    private TimetableEventTypeDAO timetableEventTypeDAO = new TimetableEventTypeDAO();

    private ParameterDAO parameterDAO = new ParameterDAO();



    protected void generate(object sender, EventArgs e)
    {
        Thread thread = new Thread(new ThreadStart(generate));
        thread.Start();

    }


    private void generate()
    {

        log.Debug("Generating Timetables in Thread");

        Semester semester = semesterDAO.findById(new Guid(SemesterListDropDown.SelectedValue));
        List<ModuleEvent> moduleEvents = new List<ModuleEvent>();

        // Looping through all module events in all cohorts 
        foreach (CohortModule cohortModule in cohortModuleDAO.getCohortModulesForSemester(semester))
        {

            log.Debug("Cohort Module Found = " + cohortModule.Module.ModuleName);

            Cohort cohort = cohortModule.Cohort;
            Module module = cohortModule.Module;


            List<ModuleEvent> cohortModuleEvents = moduleEventDAO.getUnAllocatedModuleEventBySemesterAndModule(semester, module);

            // Adding cohort information in module events
            foreach (ModuleEvent moduleEvent in cohortModuleEvents)
            {
                moduleEvent.Cohort = cohort;
                moduleEvents.Add(moduleEvent);
            }
             
        }
            
        // randomizing the order of module events such that the generation process is random
        moduleEvents = ObjectUtils.Randomize<ModuleEvent>(moduleEvents);

        // We now sort these events such that they remain random but module events requiring facilities are processed first
        moduleEvents = SortModuleEventWithFacilities(moduleEvents);

            foreach (ModuleEvent moduleEvent in moduleEvents)
            {

                log.Debug("Module Event Found = " + moduleEvent.ModuleEventLabel);
                TimetableEvent timetableEvent = timetableEventDAO.generate(semester, moduleEvent.Cohort, moduleEvent);
                /*
                timetableEvent.Module = moduleEvent.Module;
                timetableEvent.Cohort = moduleEvent.Cohort;
                timetableEvent.Semester = semester;

                timetableEvent.TimetableEventType = timetableEventTypeDAO.getGenerationEyentType();
                timetableEventDAO.insert(timetableEvent);
                 */ 
            }
        
            // Informing Timetabler Administrator that the generation process has completed if required

            Boolean sendGenerationMail = Convert.ToBoolean(parameterDAO.findParameterValue("NotifyAfterGeneration"));
            
            if (sendGenerationMail)
            {
                SendMailClient.SendGenerationEmail();
            }
    }

    private List<ModuleEvent> SortModuleEventWithFacilities(List<ModuleEvent> moduleEvents)
    {
        List<ModuleEvent> moduleEventsWithFacilities = new List<ModuleEvent>();
        List<ModuleEvent> moduleEventsWithoutFacilities = new List<ModuleEvent>();

        foreach (ModuleEvent moduleEvent in moduleEvents)
        {
            if (moduleEvent.ModuleEventFacilities != null && moduleEvent.ModuleEventFacilities.Count > 0)
            {
                moduleEventsWithFacilities.Add(moduleEvent);
            }
            else
            {
                moduleEventsWithoutFacilities.Add(moduleEvent);
            }
        }

        List<ModuleEvent> allEvents = new List<ModuleEvent>();
        allEvents.AddRange(moduleEventsWithFacilities);
        allEvents.AddRange(moduleEventsWithoutFacilities);

        return allEvents;
    }

    protected void GenerationGridView_RowCreated(object sender, GridViewRowEventArgs e)
    {
        int rowIndex = e.Row.RowIndex;
        TimetableEvent timetableEvent = (TimetableEvent)e.Row.DataItem;

        if (rowIndex > 1 && timetableEvent != null)
        {
            Literal CohortLiteralControl = (Literal)e.Row.FindControl("Cohort");
            CohortLiteralControl.Text = timetableEvent.Cohort.CohortName;

            /*
            Literal ModuleLiteralControl = (Literal)e.Row.FindControl("Module");
            ModuleLiteralControl.Text = timetableEvent.Module.ModuleName;

            Literal CourseDayLiteralControl = (Literal)e.Row.FindControl("CourseDay");
            CourseDayLiteralControl.Text = timetableEvent.CourseDay.CourseDayName;

            Literal ModuleEventLiteralControl = (Literal)e.Row.FindControl("ModuleEvent");
            ModuleEventLiteralControl.Text = timetableEvent.ModuleEvent.ModuleEventType.ModuleEventTypeName;

            Literal RoomLiteralControl = (Literal)e.Row.FindControl("Room");
            RoomLiteralControl.Text = timetableEvent.Room.RoomName;
            */
            

        }
    }
}
